package com.tanhua.server.service;


import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.upload.FastFile;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.dubbo.server.api.QuanZiApi;
import com.tanhua.dubbo.server.api.VideoApi;
import com.tanhua.dubbo.server.pojo.Video;
import com.tanhua.dubbo.server.vo.PageInfo;
import com.tanhua.server.pojo.User;
import com.tanhua.server.pojo.UserInfo;
import com.tanhua.server.utils.UserThreadLocal;
import com.tanhua.server.vo.PageResult;
import com.tanhua.server.vo.PicUploadResult;
import com.tanhua.server.vo.VideoVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class VideoService {

    @Reference(version = "1.0.0")
    private VideoApi videoApi;

    @Reference(version = "1.0.0")
    private QuanZiApi quanZiApi;

    @Autowired
    private PicUploadService picUploadService;   //上传封面到阿里云

    @Autowired
    private FastFileStorageClient fastFileStorageClient;

    @Autowired
    private FdfsWebServer fdfsWebServer;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private static final String CACHE_KEY_FREEZE_PREFIX = "FREEZE_KEY_";

    @Autowired
    private UserInfoService userInfoService;  //查询数据库

    /**
     * 保存小视频
     *
     * @param picFile   封面
     * @param videoFile 视频
     * @return
     */
    public String saveVideo(MultipartFile picFile, MultipartFile videoFile) {
        User user = UserThreadLocal.get();


        //设置查询redis的key
        String cacheKey = CACHE_KEY_FREEZE_PREFIX + user.getId().toString();
        //根据key去查询redis,判断用户是否被冻结发布
        String key = redisTemplate.opsForValue().get(cacheKey);
        if (StringUtils.equals(key,"3")){
            return null;
        }

        //创建Video对象储存视频相关信息
        Video video = new Video();
        video.setUserId(user.getId());  //用户id
        video.setSeeType(1);  //谁可见


        try {
            //上传封面到阿里云
            PicUploadResult upload = picUploadService.upload(picFile);
            //将路径添加到video对象
            video.setPicUrl(upload.getName());


            //上传视频到fastDFS
            StorePath storePath = fastFileStorageClient.uploadFile(videoFile.getInputStream(),    //IO流
                    videoFile.getSize(), //文件大小
                    StringUtils.substringAfter(videoFile.getOriginalFilename(), "."),  //文件后缀
                    null);

            //设置video文件的url前缀
            video.setVideoUrl(fdfsWebServer.getWebServerUrl() + "/" + storePath.getFullPath());
            videoApi.saveVideo(video);

            return videoApi.saveVideo(video);

        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }


    /**
     * 查询视频列表
     *
     * @param page
     * @param pageSize
     * @return
     */
    public PageResult queryVideoList(Integer page, Integer pageSize) {
        User user = UserThreadLocal.get();

        //创建返回的PageResult对象
        PageResult pageResult = new PageResult();
        //设置一些基本参数
        pageResult.setPages(0);
        pageResult.setCounts(0);
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);

        PageInfo<Video> pageInfo = null;

        //先从redis进行命中,如果命中则返回推荐列表,如果未命中查询默认列表
        String redisValue = this.redisTemplate.opsForValue().get("QUANZI_VIDEO_RECOMMEND_" + user.getId());
        if (StringUtils.isNotEmpty(redisValue)) {
            String[] pids = StringUtils.split(redisValue, ",");
            int startIndex = (page - 1) * pageSize;
            if (startIndex < pids.length) {
                int endIndex = startIndex + pageSize - 1;
                if (endIndex >= pids.length) {
                    endIndex = pids.length - 1;
                }
                List<Long> vidList = new ArrayList<>();
                for (int i = startIndex; i <= endIndex; i++) {
                    vidList.add(Long.valueOf(pids[i]));
                }

                List<Video> videoList = this.videoApi.queryVideoListByPids(vidList);
                pageInfo = new PageInfo<>();
                pageInfo.setRecords(videoList);
            }
        }


        //调用dubbo服务获取视频表
        if (null == pageInfo) {
            pageInfo = this.videoApi.queryVideoList(page, pageSize);
        }
        //获取视频表
        List<Video> records = pageInfo.getRecords();
        //创建集合封装VideoVo对象
        List<VideoVo> videoVos = new ArrayList<>();
        //创建集合储存用户id
        List<Long> userIds = new ArrayList<>();
        for (Video record : records) {
            VideoVo videoVo = new VideoVo();
            videoVo.setVideoUrl(record.getVideoUrl());  //视频路径
            videoVo.setCover(record.getPicUrl());  //封面
            videoVo.setUserId(record.getUserId());  //用户id
            videoVo.setId(record.getId().toHexString());  //动态id
            videoVo.setSignature("被锤成麻瓜了");

            //获取评论数
            Long commentCount = quanZiApi.queryCommentCount(videoVo.getId(), 2);
            videoVo.setCommentCount(commentCount.intValue());

            //获取点赞数
            String likeKey = "QUANZI_COMMENT_LIKE_" + videoVo.getId();
            String value = redisTemplate.opsForValue().get(likeKey);
            //获取不为空就设置,为空就设置为0
            if (StringUtils.isNotEmpty(value)) {
                videoVo.setLikeCount((Integer.valueOf(value)));
            } else {
                videoVo.setLikeCount(0);
            }

            //是否已赞
            String hasLikeKey = "QUANZI_COMMENT_LIKE_USER_" + user.getId() + "_" + videoVo.getId();
            videoVo.setHasLiked(redisTemplate.hasKey(hasLikeKey) ? 1 : 0);  //是否已赞(1是,0否)


            //是否关注
            String followUserKey = "VIDEO_FOLLOW_USER_" + user.getId() + "_" + videoVo.getUserId();
            videoVo.setHasFocus(this.redisTemplate.hasKey(followUserKey) ? 1 : 0); //是否关注

            //如果userIds中不存在该id就存入
            if (!userIds.contains(record.getUserId())) {
                userIds.add(record.getUserId());
            }

            videoVos.add(videoVo);
        }

        //构建查询条件
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.in("user_id", userIds);

        //查询数据库获取视频用户信息
        List<UserInfo> userInfoList = userInfoService.queryUserInfoList(queryWrapper);
        //再封装到vo类中
        for (VideoVo videoVo : videoVos) {
            for (UserInfo userInfo : userInfoList) {
                //用户一一对应
                if (videoVo.getUserId().longValue() == userInfo.getUserId().longValue()) {
                    videoVo.setAvatar(userInfo.getLogo());  //头像
                    videoVo.setNickname(userInfo.getNickName()); //名称
                    //封装完成,结束条件
                    break;
                }
            }
        }

        pageResult.setItems(videoVos);

        return pageResult;
    }

    /**
     * 用户关注
     *
     * @param followUserId 要关注的用户id
     * @return
     */
    public Boolean saveUserFocusComments(Long followUserId) {
        //获取当前用户
        User user = UserThreadLocal.get();
        //调用dubbo接口方法
        Boolean bool = videoApi.followUser(user.getId(), followUserId);
        //为空,返回false
        if (!bool) {
            return false;
        }

        //记录已经关注,存进redis中
        String followUserKey = "VIDEO_FOLLOW_USER_" + user.getId() + "_" + followUserId;
        this.redisTemplate.opsForValue().set(followUserKey, "1");

        return true;


    }

    /**
     * 取消用户关注
     *
     * @param followUserId 要关注的用户id
     * @return
     */
    public Boolean disUserFocusComments(Long followUserId) {
        //获取当前用户
        User user = UserThreadLocal.get();
        //调用dubbo接口方法
        Boolean bool = videoApi.disFollowUser(user.getId(), followUserId);
        //为空,返回false
        if (!bool) {
            return false;
        }

        //删除关注,删除redis中的记录
        String followUserKey = "VIDEO_FOLLOW_USER_" + user.getId() + "_" + followUserId;
        this.redisTemplate.delete(followUserKey);

        return true;
    }
}
